package uutalk.netcloud.talk.base.util.thirdpart;

import android.app.Activity;
import android.content.Context;
import android.text.TextUtils;

import com.apkfuns.logutils.LogUtils;
import com.tencent.gcloud.voice.GCloudVoiceEngine;
import com.tencent.gcloud.voice.IGCloudVoiceNotify;

import java.util.concurrent.TimeUnit;

import io.reactivex.Flowable;
import io.reactivex.Observable;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import uutalk.netcloud.talk.base.util.FileSaveListener;
import uutalk.netcloud.talk.base.util.TalkInterface;

/**
 * Created by hujie on 2017/8/4.
 */

public class TXGClodeVoice implements TalkInterface {

    private final static String TAG = "TXGClodeVoice";
    private GCloudVoiceEngine mVoiceEngine;
    private boolean bEngineInit = false;     // 是否已经初始化
    private String currentChannel = null;
    private Disposable disposable;
    private Context context;
    private long lastTime;//按下录音的时间

    @Override
    public void init(Context context, Activity activity, String uId) {
        if (!bEngineInit) {
            this.context = context;
            bEngineInit = true;
            mVoiceEngine = GCloudVoiceEngine.getInstance();
            mVoiceEngine.init(context, activity);
            mVoiceEngine.SetAppInfo("1694839512", "5d631f3539841e57c53e8bf824c4ae33", uId);
            mVoiceEngine.SetServerInfo("udp://cn.voice.gcloudcs.com:10001");
            mVoiceEngine.Init();
            mVoiceEngine.SetMode(GCloudVoiceEngine.Mode.RealTime);
            mVoiceEngine.CaptureMicrophoneData(true);

            mVoiceEngine.SetNotify(new IGCloudVoiceNotify() {

                @Override
                public void OnRoleChanged(int i, String s, int i1, int i2) {

                }

                @Override
                public void OnJoinRoom(int i, String s, int i1) {

                    if (i == GCloudVoiceCompleteCode.GV_ON_JOINROOM_SUCC) {
                        //加入房间成功
                        LogUtils.e("加入房间成功");
                        openSpeaker(true);
                    } else {
                        LogUtils.e("加入房间失败,重新加入");
                        Observable.timer(2000, TimeUnit.SECONDS).subscribe(aLong -> joinChannel(currentChannel, null));
                    }
                }

                @Override
                public void OnStatusUpdate(int i, String s, int i1) {
                    //三分钟还不在线就会被踢下线
                    if (i == GCloudVoiceCompleteCode.GV_ON_ROOM_OFFLINE) {
                        LogUtils.e("三分钟不在线,被T了");
                        joinChannel(currentChannel, null);
                    }
                }

                @Override
                public void OnQuitRoom(int i, String s) {
                    if (i == GCloudVoiceCompleteCode.GV_ON_QUITROOM_SUCC) {
                        LogUtils.e("退出房间成功");
                    }

                }

                @Override
                public void OnMemberVoice(int[] ints, int i) {

                    //检测有没有人在说话
                    boolean isSomeOneTalking = false;
                    for (int j = 0; j < i; j++) {
                        if (ints[2 * j + 1] == 0) {
                            continue;
                        } else {
                            isSomeOneTalking = true;
                            break;
                        }
                    }
                    // 有人说话发voiceStart,否则发voiceEnd
                    if (isSomeOneTalking) {
                        //Log.e("pmt", "有人说话");
                        //BlueUtils.getInstance().sendVoiceStart();
                    } else {
                        //Log.e("pmt", "oo没有人说话");
                        //BlueUtils.getInstance().sendVoiceEnd();
                    }
                    //Log.e("pmt", "房间人数：》》" + ints.length);
                }

                @Override
                public void OnMemberVoice(String s, int i, int i1) {
                    if (i1 != 0) {
                    } else {
                    }
                }

                @Override
                public void OnUploadFile(int i, String s, String s1) {

                }

                @Override
                public void OnDownloadFile(int i, String s, String s1) {

                }

                @Override
                public void OnPlayRecordedFile(int i, String s) {

                }

                @Override
                public void OnApplyMessageKey(int i) {

                }

                @Override
                public void OnSpeechToText(int i, String s, String s1) {

                }

                @Override
                public void OnRecording(char[] chars, int i) {
                    if (fileSaveListener != null) {
                        byte[] bytes = charsToBytes(chars, i);
                        fileSaveListener.onRecording(bytes);
                    }

                }

                @Override
                public void OnStreamSpeechToText(int i, int i1, String s, String s1) {

                }


            });
            poll();
        }

        PCMManager.getInstance().startUploadTask();

    }


    @Override
    public void joinChannel(String channelId, String uId) {
        if (mVoiceEngine != null && channelId != null) {
            Observable.timer(200, TimeUnit.MILLISECONDS).subscribe(aLong -> {
                currentChannel = channelId;
                LogUtils.e("加入房间" + currentChannel);
                int i = mVoiceEngine.JoinTeamRoom(channelId, 30000);
                if (i == 8193) {
                    leaveChannel();
                    joinChannel(currentChannel, null);
                }
                LogUtils.e("加入房间返回状态->" + i);
            });
        }

    }

    @Override
    public void pauseChannel() {
        if (mVoiceEngine != null) {
            mVoiceEngine.Pause();
        }
    }

    @Override
    public void resumeChannel() {
        if (mVoiceEngine != null) {
            mVoiceEngine.Resume();
        }
    }

    @Override
    public void leaveChannel() {
        if (mVoiceEngine != null) {
            if (currentChannel != null) {
                mVoiceEngine.QuitRoom(currentChannel, 30000);
                currentChannel = null;
            }
        }
    }

    @Override
    public int getMicLevel() {
        if (mVoiceEngine != null) {
            return mVoiceEngine.GetMicLevel();
        }
        return 0;
    }

    public static byte[] charsToBytes(char[] chars, int count) {
        byte bytes[] = new byte[count / 2];
        for (int i = 0; i < count / 2; i++) {
            bytes[i] = (byte) ((chars[i] & 0xFF00) >> 8);
        }
        return bytes;
    }


    FileSaveListener fileSaveListener;

    @Override
    public void openMic(boolean open) {
        if (open) {
            LogUtils.e("按下开始说话");
            lastTime = System.currentTimeMillis();
            fileSaveListener = new FileSaveListener();
            fileSaveListener.onStartRecording(context, lastTime + "");
            mVoiceEngine.OpenMic();
        } else {
            mVoiceEngine.CloseMic();
            if (fileSaveListener != null) {
                fileSaveListener.onEndRecording();
                if(TextUtils.isEmpty(currentChannel)) return;
                //不足1秒，不保存记录
                long voice_length = (System.currentTimeMillis() - lastTime) / 1000;
                if (voice_length > 0) {
                    PCMManager.getInstance().savePCMData(fileSaveListener.getTtsFile(), currentChannel, voice_length);
                }
                fileSaveListener = null;
            }
        }
    }

    @Override
    public void openSpeaker(boolean open) {
        if (open) {
            mVoiceEngine.OpenSpeaker();
        } else {
            mVoiceEngine.CloseSpeaker();
        }
    }


    @Override
    public String getCurrentChannel() {
        return currentChannel;
    }

    private void poll() {
        if (disposable != null && !disposable.isDisposed()) {
            return;
        }
        disposable = Flowable.interval(100, TimeUnit.MILLISECONDS).subscribe(new Consumer<Long>() {
            @Override
            public void accept(@NonNull Long aLong) throws Exception {
                if (mVoiceEngine != null) {
                    mVoiceEngine.Poll();
                }
            }
        });
    }

    private void stopPoll() {
        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
            disposable = null;
        }
    }


    @Override
    public void destory() {
        stopPoll();
        if (bEngineInit) {
            bEngineInit = false;
            openSpeaker(false);
            openMic(false);
            mVoiceEngine = null;
        }
    }



    public GCloudVoiceEngine getVoiceEngine() {
        return mVoiceEngine;
    }
}
